package com.hjq.fcloud.utils

import android.app.Activity
import android.app.Application
import android.content.Context
import android.net.ConnectivityManager
import android.net.Network
import android.os.Build
import androidx.core.content.ContextCompat
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import com.google.gson.reflect.TypeToken
import com.google.gson.stream.JsonToken
import com.hjq.bar.TitleBar
import com.hjq.fcloud.R
import com.hjq.fcloud.http.model.RequestHandler
import com.hjq.fcloud.http.model.RequestServer
import com.hjq.fcloud.manager.ActivityManager
import com.hjq.fcloud.other.AppConfig
import com.hjq.fcloud.other.CrashHandler
import com.hjq.fcloud.other.DebugLoggerTree
import com.hjq.fcloud.other.MaterialHeader
import com.hjq.fcloud.other.SmartBallPulseFooter
import com.hjq.fcloud.other.TitleBarStyle
import com.hjq.fcloud.other.ToastLogInterceptor
import com.hjq.fcloud.other.ToastStyle
import com.hjq.fcloud.update.OKHttpUpdateHttpService
import com.hjq.fcloud.widget.loadandretry.LoadingAndRetryManager
import com.hjq.gson.factory.GsonFactory
import com.hjq.http.EasyConfig
import com.hjq.http.config.IRequestApi
import com.hjq.http.model.HttpHeaders
import com.hjq.http.model.HttpParams
import com.hjq.toast.ToastUtils
import com.hjq.umeng.UmengClient
import com.scwang.smart.refresh.layout.SmartRefreshLayout
import com.scwang.smart.refresh.layout.api.RefreshLayout
import com.tencent.bugly.crashreport.CrashReport
import com.tencent.mmkv.MMKV
import com.xuexiang.xupdate.XUpdate
import com.xuexiang.xupdate.entity.UpdateError.ERROR
import com.xuexiang.xupdate.utils.UpdateUtils
import okhttp3.OkHttpClient
import timber.log.Timber
import java.util.concurrent.TimeUnit

object SdkHelper {

    private val TAG = SdkHelper::class.java.simpleName

    /**
     * 初始化一些第三方框架
     */
    fun initSdk(application: Application?) {
        application?.let {
            // 设置标题栏初始化器
            TitleBar.setDefaultStyle(TitleBarStyle())

            // 设置全局的 Header 构建器
            SmartRefreshLayout.setDefaultRefreshHeaderCreator{ context: Context, layout: RefreshLayout ->
                MaterialHeader(context).setColorSchemeColors(ContextCompat.getColor(context, R.color.common_accent_color))
            }
            // 设置全局的 Footer 构建器
            SmartRefreshLayout.setDefaultRefreshFooterCreator{ context: Context, layout: RefreshLayout ->
                SmartBallPulseFooter(context)
            }
            // 设置全局初始化器
            SmartRefreshLayout.setDefaultRefreshInitializer { context: Context, layout: RefreshLayout ->
                // 刷新头部是否跟随内容偏移
                layout.setEnableHeaderTranslationContent(true)
                    // 刷新尾部是否跟随内容偏移
                    .setEnableFooterTranslationContent(true)
                    // 加载更多是否跟随内容偏移
                    .setEnableFooterFollowWhenNoMoreData(true)
                    // 内容不满一页时是否可以上拉加载更多
                    .setEnableLoadMoreWhenContentNotFull(false)
                    // 仿苹果越界效果开关
                    .setEnableOverScrollDrag(false)
            }

            // 初始化吐司
            ToastUtils.init(application, ToastStyle())
            // 设置调试模式
            ToastUtils.setDebugMode(AppConfig.isDebug())
            // 设置 Toast 拦截器
            ToastUtils.setInterceptor(ToastLogInterceptor())

            // 本地异常捕捉
            CrashHandler.register(application)

            // 友盟统计、登录、分享 SDK
            UmengClient.init(application, AppConfig.isLogEnable())

            // Bugly 异常捕捉
            CrashReport.initCrashReport(application, AppConfig.getBuglyId(), AppConfig.isDebug())

            // Activity 栈管理初始化
            ActivityManager.getInstance().init(application)

            // MMKV 初始化
            MMKV.initialize(application)

            initOkHttp(application)

            // 初始化日志打印
            if (AppConfig.isLogEnable()) {
                Timber.plant(DebugLoggerTree())
            }

            registerConnectivityManager(application)


            initLoadingAndRetryManager()

            initXUpdate(application)
        }
    }


    private fun initXUpdate(application: Application) {
        XUpdate.get()
            .debug(false)
            .isWifiOnly(false) //默认设置只在wifi下检查版本更新
            .isGet(true) //默认设置使用get请求检查版本
            .isAutoMode(false) //默认设置非自动模式，可根据具体使用配置
            .param("versionCode", UpdateUtils.getVersionCode(application)) //设置默认公共请求参数
            .param("appKey", application.packageName)
            .setOnUpdateFailureListener { error ->

                //设置版本更新出错的监听
                if (error.code != ERROR.CHECK_NO_NEW_VERSION) {          //对不同错误进行处理
                    ToastUtils.show(error.toString())
                }
            }
            .supportSilentInstall(true) //设置是否支持静默安装，默认是true
            .setIUpdateHttpService(OKHttpUpdateHttpService()) //这个必须设置！实现网络请求功能。
            .init(application) //这个必须初始化
    }
    private fun initLoadingAndRetryManager() {
        LoadingAndRetryManager.BASE_RETRY_LAYOUT_ID = R.layout.base_layout_net_error
        LoadingAndRetryManager.BASE_LOADING_LAYOUT_ID = R.layout.dialog_loading
//        LoadingAndRetryManager.BASE_LOADING_LAYOUT_ID = R.layout.base_layout_loading;//初始化时的进度条，并没有什么用，2020/5/20
        //        LoadingAndRetryManager.BASE_LOADING_LAYOUT_ID = R.layout.base_layout_loading;//初始化时的进度条，并没有什么用，2020/5/20
        LoadingAndRetryManager.BASE_EMPTY_LAYOUT_ID = R.layout.base_layout_empty
    }

    private fun registerConnectivityManager(application: Application) {
        // 注册网络状态变化监听
        val connectivityManager: ConnectivityManager? =
            ContextCompat.getSystemService(application, ConnectivityManager::class.java)
        if (connectivityManager != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            connectivityManager.registerDefaultNetworkCallback(object :
                ConnectivityManager.NetworkCallback() {
                override fun onLost(network: Network) {
                    val topActivity: Activity? = ActivityManager.getInstance().getTopActivity()
                    if (topActivity !is LifecycleOwner) {
                        return
                    }
                    val lifecycleOwner: LifecycleOwner = topActivity
                    if (lifecycleOwner.lifecycle.currentState != Lifecycle.State.RESUMED) {
                        return
                    }
                    ToastUtils.show(R.string.common_network_error)
                }
            })
        }
    }

    private fun initOkHttp(application: Application) {
        // 网络请求框架初始化
        val okHttpClient: OkHttpClient = OkHttpClient.Builder()
            .connectTimeout(60000, TimeUnit.MILLISECONDS)
            .readTimeout(60000,TimeUnit.MILLISECONDS)
            .writeTimeout(60000,TimeUnit.MILLISECONDS)
            .build()

        EasyConfig.with(okHttpClient)
            // 是否打印日志
            .setLogEnabled(AppConfig.isLogEnable())
            // 设置服务器配置
            .setServer(RequestServer())
            // 设置请求处理策略
            .setHandler(RequestHandler(application))
            // 设置请求重试次数
            .setRetryCount(1)
            .addParam("client_type", "2")
            .setInterceptor { api: IRequestApi, params: HttpParams, headers: HttpHeaders ->
                // 添加全局请求头
                headers.put("TOKEN", AppConfigUtils.token)
                //上传文件替换，但是经常会上传失败。unexpected end of stream on      或者              \n not found: limit=0 content=…
                headers.put("Accept-Encoding", "identity")
                headers.put("Connection", "close")
            }
            .into()

        // 设置 Json 解析容错监听
        GsonFactory.setJsonCallback { typeToken: TypeToken<*>, fieldName: String?, jsonToken: JsonToken ->
            // 上报到 Bugly 错误列表
            CrashReport.postCatchedException(IllegalArgumentException("类型解析异常：$typeToken#$fieldName，后台返回的类型为：$jsonToken"))
        }
    }

}